/**
 * 无向图，每个点有一个颜色Col[i]，直接在本点生成颜色需要Cost[i]
 * 可以把颜色沿着边传播，每条边有一个花费w，同时从u到v，颜色需要从Col[u]变为Col[v]
 * 事先给出K对颜色变换方案，从 x 到 y 需要花费 z
 * 不同颜色的总数是100
 * 问是每个点均有颜色的最小花费是多少
 * 关键是颜色变换方案，不能直接用，需要使用Floyd算法求出最小值
 * 同时注意到，可以允许有些颜色不可变换，即可能某些边实际上是不通的
 * 注意到每次到达某个点的时候，颜色必然变为与该点相同，因此颜色本身并不重要，只是单纯的到达即可
 * 只需考虑边的花费与变换的花费即可，这些都是固定的，可以统一算到边权当中
 * 因此跑一个最短路即可。
 * 注意最大值不能开到最大，因为中间存在加法，可能溢出导致错误
 */
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;

using llt = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;

llt const INF = 0x3F8F9FAFBFCFDFEF;

int C, K;
vector<vector<llt>> Tran;

int N, M;
vi Col;
vector<vector<pair<int, llt>>> G;

void input(){
    cin >> C >> K;
    Tran.assign(C + 1, vector<llt>(C + 1, INF));
    for(int i=1;i<=C;++i)Tran[i][i] = 0;
    for(int x,y,z,i=0;i<K;++i){
        cin >> x >> y >> z;
        Tran[x][y] = min(Tran[x][y], z+0LL);
    }
    // Floyd
    for(int k=1;k<=C;++k)for(int i=1;i<=C;++i)for(int j=1;j<=C;++j){
        Tran[i][j] = min(Tran[i][j], Tran[i][k] + Tran[k][j]);
    }

    cin >> N;
    Col.assign(N + 1, {});
    for(int i=1;i<=N;++i){
        cin >> Col[i];
    }

    G.assign(N + 1, {});
    for(int c,i=1;i<=N;++i){
        cin >> c;
        G[0].push_back({i, c});
    }

    cin >> M;
    for(int u,v,w,i=0;i<M;++i){
        cin >> u >> v >> w;
        auto cu = Col[u], cv = Col[v];
        G[u].push_back({v, w + Tran[cu][cv]});
        G[v].push_back({u, w + Tran[cv][cu]});
    }
    return;
}

__gnu_pbds::priority_queue<pair<llt, int>, function<bool(pair<llt, int>, pair<llt, int>)>> Q([](pair<llt, int> a, pair<llt, int> b){
    if(a.first != b.first) return a.first > b.first;
    return a.second > b.second;
});

vector<llt> D;

llt proc(){
    D.assign(N + 1, INF);
    Q.clear();
    Q.push({D[0] = 0, 0});
    vi flag(N + 1, 0);

    while(1){
        while(not Q.empty() and flag[Q.top().second]) Q.pop();
        if(Q.empty()) break;

        auto h = Q.top(); Q.pop();
        flag[h.second] = 1;

        int v; llt tmp;
        for(const auto & p : G[h.second]){
            if(not flag[v = p.first] and (D[v] > (tmp = h.first + p.second))){
                Q.push({D[v] = tmp, v});
            }
        }
    }

    return accumulate(D.begin(), D.end(), 0LL);
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--){
        input();
        cout << proc() << "\n";
    }
    return 0;
}